/* 
 * dosheader\callback.cpp
 * Written by, Sohail Qayum Malik[sqm@cyberian.pk]
 */

/* For debuging purposes, should be gone when done */
#include <iostream>
/*  For debugging purposes ends here */

#include <stdio.h>  
#include "callback.h"

int callback_dosheader_dump(int argc, ...) {

   int ret = 0;
      
   return ret;
}

int callback_dosheader(int argc, ...) { 
 
   int ret = 0;  
   size_t size = 0;
   void *ptr = NULL;
   va_list VList;
   PIMAGE_DOS_HEADER dosheader = NULL;   
   //IMAGE_NT_HEADERS, which is defined in WINNT.H. This structure is composed of a DWORD and two substructures and is laid out as follows
   /* DWORD Signature;
      IMAGE_FILE_HEADER FileHeader;
      IMAGE_OPTIONAL_HEADER32/64 OptionalHeader; */
#ifdef _WIN64
   PIMAGE_NT_HEADERS64 ntheader = NULL;
#else   
   PIMAGE_NT_HEADERS32 ntheader = NULL;
#endif    
      
   va_start(VList, argc);
   
   dosheader = va_arg(VList, PIMAGE_DOS_HEADER);
#ifdef _WIN64   
   ntheader = va_arg(VList, PIMAGE_NT_HEADERS64);
#else   
   ntheader = va_arg(VList, PIMAGE_NT_HEADERS32);
#endif   
   size = va_arg(VList, size_t);
   ptr = va_arg(VList, void *);
   
   va_end(VList);
   
   if ( dosheader && dosheader->e_magic == IMAGE_DOS_SIGNATURE ) {
   

/*   
      std::cout<<"e_lf = "<<dosheader->e_lfanew<<std::endl;
	  std::cout<<"sizeof(IMAGE_DOS_HEADER) = "<<sizeof(IMAGE_DOS_HEADER)<<std::endl;
	  std::cout<<"e_lf - sizeof(IMAGE_DOS_HEADER) = "<<dosheader->e_lfanew - sizeof(IMAGE_DOS_HEADER)<<std::endl;

      std::cout<<"Size of IMAGE_DOS_HEADER = "<<sizeof(IMAGE_DOS_HEADER)<<std::endl;	  
	  std::cout<<"size = "<<size<<std::endl; 
*/	  
	  
	  	  	  	  	    	  
	  printf("\nDump of IMAGE_DOS_HEADER(MS-DOS stub header).\n");
	  printf("------------------------------------------------\n");
	  printf("Magic number                                                 :- %c%c\n", ((char *)&dosheader->e_magic)[0], ((char *)&dosheader->e_magic)[1]);
	  printf("Bytes on last page(512 bytes) of file                        :- %u\n", dosheader->e_cblp);  
	  printf("Pages(a page is 512 bytes entity) in file                    :- %u\n", dosheader->e_cp);
	  printf("Relocations                                                  :- %u\n", dosheader->e_crlc);
	  printf("Size of header in paragraphs(a paragraph is 16 bytes entity) :- %u\n", dosheader->e_cparhdr);
	  printf("Minimum extra paragraphs needed                              :- %u\n", dosheader->e_minalloc);
	  printf("Maximum extra paragraphs needed                              :- %u\n", dosheader->e_maxalloc);
	  printf("Initial SS value(in paragraphs and relative to loadmodule)   :- 0x%.4x\n", dosheader->e_ss);
	  printf("Initial SP value                                             :- 0x%.4x\n", dosheader->e_sp); 
	  printf("Checksum                                                     :- %u\n", dosheader->e_csum);
	  printf("Initial IP value(byte number, a displacement into CS)        :- 0x%.4x\n", dosheader->e_ip);
	  printf("Initial CS value(in paragraphs and relative to loadmodule)   :- 0x%.4x\n", dosheader->e_cs); 
	  printf("File address of relocation table                             :- %u\n", dosheader->e_lfarlc);
	  printf("Overlay number                                               :- %u\n", dosheader->e_ovno);
	  printf("...\n");
	  printf("...\n");
	  printf("...\n");
	  printf("...\n");
	  printf("File address of new exe header(where IMAGE_NT_HEADERS begins):- %u\n\n", dosheader->e_lfanew);
	  
	  printf("loadmodule = The actual code which is compiled/assembled into an EXE file format(what ever is after the relocation table). The paragraph address where the loadmodule gts loaded by DOS is added to initial values(paragraph addresses) of CS and SS segment registers of EXE header).\n");
	  printf("Relocation Table = An array of segmented addresses. At run time each such address gets updated by adding the paragraph number of CS in the segment portion of the segmented address.\n");
	  printf("The size of the header is the aggregate of IMAGE_DOS_HEADER and relocation table.\n");
	  
	  if ( ptr ) {
	  
	     printf("\nDump of MS-DOS stub.\n");
		 printf("-----------------------\n");
	  
	     for ( size_t i = 0; i < size; i++ ) {
		 
#ifdef	_WIN64
			printf("%.16x  ", i);
#else
			printf("%.8x  ", i);
#endif		 
		 
		     for ( size_t j = 0; j < 16; j++ ) {
			 
			     printf("%.2x ", *(((unsigned char *)ptr) + i + j));
			 }
			 
			 printf("  ");
			 
		     for ( size_t j = 0; j < 16; j++ ) {
			 
			     if ( *(((unsigned char *)ptr) + i + j) > 31 )
			        printf("%c", *(((char *)ptr) + i + j));
				 else 
                    printf(".");				 
			 }			 
			 			 						 			 			 
			 i+=16;
			 
			 printf("\n");
		 }
	  
	      
	  }

/*	  
	  for ( unsigned int i = 0; i < size; i++ ) {
	  
	     printf("%c", ((char *)ptr)[i] );  
	  }
	  
	  printf( "\n" );
*/	  
	  
   }
   else { 
      ret = -1;   
   }	  
   
   return ret;
}	
